package com.study.springbootsecurity.handler.pass;

import com.study.springbootsecurity.config.properties.JwtConfigProperties;
import com.study.springbootsecurity.constants.JwtTokenConstants;
import com.study.springbootsecurity.service.AccessTokenBlackService;
import com.study.springbootsecurity.service.impl.TokenService;
import com.study.springbootsecurity.util.*;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import java.io.IOException;

/**
 * @Description: TODO 退出登录处理器
 * @author: Huangjianyun
 * @date: 2025-06-11 4:32
 */
public class LogoutTokenSuccessHandler implements LogoutSuccessHandler {

    private final AccessTokenBlackService blackService;
    private final JwtConfigProperties jwtConfigProperties;
    private final TokenService tokenService;
    public LogoutTokenSuccessHandler(AccessTokenBlackService blackService,TokenService tokenService,JwtConfigProperties jwtConfigProperties) {
        this.blackService = blackService;
        this.tokenService = tokenService;
        this.jwtConfigProperties = jwtConfigProperties;
    }

    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {


        // request请求获取访问令牌是否符合校验规则
        String accessTokenHeader = request.getHeader(JwtTokenConstants.JWT_TOKEN_HEADER);
        String accessToken = accessTokenHeader.replace(JwtTokenConstants.JWT_TOKEN_PREFIX, "");
        String username = TokenUtil.getUsernameFromToken(accessToken, jwtConfigProperties);
        // 设备标识符
        String deviceFingerprint = DeviceFinerUtil.buildDeviceFingerprint(request);
        //1 清空cookie的刷新令牌
        CookieUtil.deleteCookie(response, "refresh_token", "/", true, true);
        //2 accessToken访问令牌添加黑名单 blacklist:access_token:设备标识:username value: accessToken
        blackService.addToBlacklist(deviceFingerprint,username,accessToken,jwtConfigProperties.getExpiration());
        //3 清空redis存储刷新令牌
        String refreshTokenKey = "refresh"+":"+username + ":"+deviceFingerprint;
        tokenService.deleteRefreshToken(refreshTokenKey);
        // 4 清空redis存储用户信息
        String userKey = "user:info:"+username+":"+deviceFingerprint;
        tokenService.deleteUserInfo(userKey);
        //4 清空securityContext上下文信息数据
        SecurityContextHolder.clearContext();
        //5 使用响应工具类诙谐消息给前端 401未登录
         ResponseUtil.outJson(response,Result.fail(200,"退出登录成功"));
    }
}
